import * as React from 'react';
import { PureComponent } from 'react';
import { IUser, State } from './reducer';
import { connect, Dispatch } from 'react-redux';
import {
    ActionAddUser, ActionClear, ActionDelUser, ActionSetCoefficient, ActionSetTotal, ActionSetValue, ActionToggleIsFixed
} from './action';
import Row from "antd/lib/grid/row";
import Col from "antd/lib/grid/col";
import Button from "antd/lib/button/button";
import Message from 'antd/lib/message';
import Table from "antd/lib/table/Table";
import Select from "antd/lib/select";
import InputNumber from "antd/lib/input-number";
import Modal from "antd/lib/modal/Modal";
import Icon from "antd/lib/icon";
import BackTop from "antd/lib/back-top";

const Option = Select.Option;

const style = require('./index.scss');
const numeral = require('numeral');

interface IStateProps {
    total: number
    userList: IUser[]
}

interface IDispatchProps {
    clear: () => void
    addUser: (name: string[]) => void
    delUser: (indexList: number[]) => void
    toggleIsFixed: (index: number, isFixed: boolean) => void
    setValue: (index: number, value: number) => void
    setCoefficient: (index: number, coefficient: number) => void
    setTotal: (total: number) => void
}

const mapStateToProps = (state: State): IStateProps => ({
    total: state.total,
    userList: state.userList
});

const mapDispatchToProps = (dispatch): IDispatchProps => ({
    clear: () => dispatch({ ...new ActionClear() }),
    addUser: nameList => dispatch({ ...new ActionAddUser(nameList) }),
    delUser: indexList => dispatch({ ...new ActionDelUser(indexList) }),
    toggleIsFixed: (index, isFixed) => dispatch({ ...new ActionToggleIsFixed({ index, isFixed }) }),
    setValue: (index, value) => dispatch({ ...new ActionSetValue({ index, value }) }),
    setCoefficient: (index, coefficient) => dispatch({ ...new ActionSetCoefficient({ index, coefficient }) }),
    setTotal: total => dispatch({ ...new ActionSetTotal(total) })
});

class AppBasic extends PureComponent<IStateProps & IDispatchProps> {

    addUser = () => {
        const name = window.prompt('请输入姓名，添加多个请使用逗号分隔，姓名相同时自动去重！');

        if (name === null) return;

        // 逗号分隔
        let nameList = name.split(',');
        // 中文逗号也支持一下。。。
        nameList = nameList.reduce((last, next) => {
            return last.concat(next.split('，'))
        }, []).filter(v => !!v);

        if (nameList.length > 0) {
            this.props.addUser(Array.from(new Set(nameList)));
        } else {
            Message.error('名字不能为空！')
        }
    };

    getTableSource = () => {
        const { userList, total } = this.props;

        let totalCoefficient = 0;
        let totalValue = total;

        userList.forEach(user => {
            if (user.isFixed) {
                totalValue -= user.value;
            } else {
                totalCoefficient += user.coefficient;
            }
        });

        userList.forEach(user => {
            if (user.isFixed) {
                user.bonus = user.value
            } else {
                user.bonus = totalValue * user.coefficient / totalCoefficient
            }
        });
        return userList;
    };

    getTableColumns = () => {
        const columns = [{
            title: '姓名',
            dataIndex: 'name',
            key: 'name'
        }, {
            title: '发放方式',
            dataIndex: 'isFixed',
            key: 'isFixed',
            render: (text, record, index) => (
                <Select value={String(text)} style={{ width: 120 }} onChange={isFixed => {
                    this.props.toggleIsFixed(index, isFixed === 'true');
                }}>
                    <Option value={"false"}>比例系数</Option>
                    <Option value={"true"}>固定奖金</Option>
                </Select>
            )
        }, {
            title: '比例系数/固定奖金',
            dataIndex: 'coefficient',
            key: 'coefficient',
            render: (text, record, index) => {
                const { isFixed, value, coefficient } = record;
                if (isFixed) {
                    return (
                        <InputNumber min={0} value={value} placeholder={"请输入固定金额"} style={{ width: 200 }}
                                     key={isFixed}
                                     onChange={v => {
                                         // 判断一下固定金额是否超过了总额
                                         const { userList, total } = this.props;
                                         const bonus = userList.reduce((last, next) => {
                                             if (next.isFixed) {
                                                 last += next.value
                                             }
                                             return last
                                         }, 0);
                                         if (bonus + Number(v) > total) {
                                             /*                                             Modal.error({
                                                                                              title: '当前奖金超出了奖金总额！',
                                                                                              content: (
                                                                                                  <div>
                                                                                                      <p>如果给
                                                                                                          <span className={style.strong}>
                                                                                                              {` ${record.name} `}
                                                                                                          </span>
                                                                                                          设置固定奖金为
                                                                                                          <span className={style.strong}>
                                                                                                              {` ${numeral(Number(v)).format('0,0')} `}
                                                                                                          </span>
                                                                                                          , 则固定奖金总额超出了奖金总额。
                                                                                                      </p>
                                                                                                  </div>
                                                                                              )
                                                                                          });*/

                                             Message.error('当前固定奖金总额超出了奖金总额！');
                                             this.props.setValue(index, Number(0));
                                         } else {
                                             this.props.setValue(index, Number(v));
                                         }

                                     }}/>
                    )
                } else {
                    return (
                        <InputNumber min={0} defaultValue={coefficient} placeholder={"请输入比例系数"} style={{ width: 200 }}
                                     key={isFixed}
                                     onChange={v => {
                                         this.props.setCoefficient(index, Number(v));
                                     }}/>
                    )
                }
            }
        }, {
            title: '奖金',
            dataIndex: 'bonus',
            key: 'bonus',
            render: text => {
                if (text > 10000) {
                    return (
                        <span className={style.bonus}>
                            <Icon style={{ fontWeight: "normal" }} type="taobao-circle"/>
                            <span
                                className={style.bonus}>{` ${numeral(text).format('0,0.00')}`}</span>
                        </span>
                    )
                } else if (text > 5000) {
                    return (
                        <span className={style.bonus}>
                             <Icon style={{ fontWeight: "normal" }} type="like-o"/> {numeral(text).format('0,0.00')}
                        </span>
                    )
                } else if (text > 0) {
                    return (
                        <span className={style.bonus}>
                            <Icon style={{ fontWeight: "normal" }} type="smile-o"/> {numeral(text).format('0,0.00')}
                        </span>
                    )
                } else {
                    return (
                        <span className={style.bonus}>
                            <Icon style={{ fontWeight: "normal" }} type="frown-o"/> 0
                        </span>
                    )
                }
            }
        }, {
            title: '操作',
            render: (text, record, index) => (
                <Icon type="close-circle-o" className={style['del-user']} onClick={() => {
                    this.props.delUser([index])
                }}/>)
        }];
        return columns;
    };

    render() {

        const { total } = this.props;

        return (
            <div className={style.wrap}>
                <h1 className={style.title}>奖金分配计算器</h1>
                <div className={style.header}>
                    <Row>
                        <Col span={16} offset={4}>
                            <span className={style.total}>奖金总额：  </span>
                            <InputNumber size="small" style={{ width: 200 }} min={0}
                                         value={total}
                                         formatter={value => {
                                             return numeral(value).format('0,0')
                                         }}
                                         parser={str => {
                                             if (str) {
                                                 return numeral(str).value()
                                             } else {
                                                 return 0
                                             }
                                         }}
                                         onChange={v => {
                                             if (Number(v) < 0 || isNaN(Number(v))) {
                                                 Message.error('总额必须为非负整数');
                                                 this.props.setTotal(0);
                                             } else {
                                                 this.props.setTotal(Number(v))
                                             }
                                         }}/>
                        </Col>
                    </Row>
                </div>
                <div className={style.body}>
                    <Row>
                        <Col span={20} offset={4}>
                            <Button size={"small"} type={"primary"} icon={"plus-circle-o"}
                                    onClick={this.addUser}>
                                添加成员
                            </Button>
                            <Button size={"small"} type={"danger"} icon={"delete"} style={{ marginLeft: 10 }}
                                    onClick={this.props.clear}>
                                清空所有
                            </Button>
                        </Col>
                    </Row>
                    <p/>
                    <Row>
                        <Col offset={4} span={16}>
                            <Table size={"small"} dataSource={this.getTableSource()} columns={this.getTableColumns()}
                                   rowKey={"name"} pagination={false}/>
                        </Col>
                    </Row>
                </div>
                <div>
                    <BackTop/>
                </div>
            </div>
        )
    }
}

const App = connect(mapStateToProps, mapDispatchToProps)(AppBasic);

export default App;
